package com.service.scheduling.task;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.dto.MemberRank;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.GradeEnum;
import com.service.dao.enums.MemberJAType;
import com.service.dao.enums.MinerStatusEnum;
import com.service.dao.model.Member;
import com.service.dao.model.RankMiningPoolRecord;
import com.service.dao.model.SysConfig;
import com.service.dao.model.SysQuotesIpfx;
import com.service.scheduling.constants.IPFSConstant;
import com.service.scheduling.dto.MemberStoreChange;
import com.service.scheduling.service.ConfigService;
import com.service.scheduling.service.OrderProductHrComboService;
import com.service.scheduling.service.RankMiningPoolRecordService;
import com.service.scheduling.service.SysQuotesIpfxService;
import com.service.scheduling.utils.MathUtil;
import com.service.scheduling.utils.MemCacheNoTran;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 每日矿池奖池增量
 * @Author: ty
 * @Date: 2021/5/8 14:21
 * @param:
 * @return:
 **/
@Slf4j
@Component
public class MiningPoolRankAddTask {
	@Autowired
	private OrderProductHrComboService orderProductHrComboService;
	@Autowired
	private RankMiningPoolRecordService rankMiningPoolRecordService;
	@Autowired
	private SysQuotesIpfxService sysQuotesIpfxService;
	@Autowired
	private MemCacheNoTran memCache;
	@Autowired
	private ConfigService configService;

	private static BigDecimal baseNum = new BigDecimal(100L);

//	@Scheduled(cron = "0 0 0 * * ?")
	public void poolRewardAdd() {
		Date currentMonth = new Date();
		String minerStatus = configService.getByConfigName(ConfigConstants.MINER_STATUS).getConfValue();
		if(MinerStatusEnum.OFF.equals(minerStatus)){
			log.info("矿机暂停运行......");
			return;
		}
		Date lastMonth = DateUtils.addMonths(currentMonth, -1);
		Date nextMonth = DateUtils.addMonths(currentMonth, 1);
		String dayPattern = "yyyy-MM-dd HH:mm:ss";
		String monthPattern = "yyyy-MM";
		String currentDateStr = DateFormatUtils.format(currentMonth, dayPattern);
		String currentMonthStr = DateFormatUtils.format(currentMonth, monthPattern);//本月
		String lastMonthStr = DateFormatUtils.format(lastMonth, monthPattern);//上个月
		String nextMonthStr = DateFormatUtils.format(nextMonth, monthPattern);//下个月
		//统计全网已购有效算力总量
		BigDecimal totalHashRate = orderProductHrComboService.totalAllPlatformHashRate();
		if (totalHashRate.compareTo(BigDecimal.ZERO) == 0) {
			log.info("{}平台有效总算力为0，退出奖池额度新增任务...", currentDateStr);
		}
		//获取本月矿池奖励额度记录
		RankMiningPoolRecord currentRankMiningPoolRecord = rankMiningPoolRecordService.getSomeMonthRecord(currentMonthStr);
		if (ObjectUtils.isEmpty(currentRankMiningPoolRecord)) {
			//获取今日fil挖矿效率
			SysQuotesIpfx ipfxConfig = JSONObject.parseObject(memCache.get(IPFSConstant.REDIS_IPFS_KEY), SysQuotesIpfx.class);
			if (ObjectUtils.isEmpty(ipfxConfig)) {
				LambdaQueryWrapper<SysQuotesIpfx> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.orderByDesc(SysQuotesIpfx::getUpdateTime);
				queryWrapper.last("limit 1");
				ipfxConfig = sysQuotesIpfxService.getOne(queryWrapper);
			}
			BigDecimal dailyOutRate = new BigDecimal(ipfxConfig.getPer_24h_rewards().replace(" FIL/TiB", ""));
			Map<String, SysConfig> configMap = configService.mapByConfigGroup(ConfigConstants.Group.award.getCode());

			firstSaveRankMiningPoolRecord(totalHashRate, dailyOutRate, configMap);
		} else {
			//获取今日fil挖矿效率
			SysQuotesIpfx ipfxConfig = JSONObject.parseObject(memCache.get(IPFSConstant.REDIS_IPFS_KEY), SysQuotesIpfx.class);
			if (ObjectUtils.isEmpty(ipfxConfig)) {
				LambdaQueryWrapper<SysQuotesIpfx> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.orderByDesc(SysQuotesIpfx::getUpdateTime);
				queryWrapper.last("limit 1");
				ipfxConfig = sysQuotesIpfxService.getOne(queryWrapper);
			}
			BigDecimal dailyOutRate = new BigDecimal(ipfxConfig.getPer_24h_rewards().replace(" FIL/TiB", ""));
			Map<String, SysConfig> configMap = configService.mapByConfigGroup(ConfigConstants.Group.award.getCode());
			updateRankMiningPoolRecord(currentRankMiningPoolRecord, totalHashRate, dailyOutRate, configMap);
		}
	}

	/**
	 * @Description: 首次添加矿池月奖励记录
	 * @Author: ty
	 * @Date: 2021/5/8 14:56
	 * @param: [totalHashRate, dailyOutRate, configMap]
	 * @return: com.service.dao.model.RankMiningPoolRecord
	 **/
	public RankMiningPoolRecord firstSaveRankMiningPoolRecord(BigDecimal totalHashRate, BigDecimal dailyOutRate, Map<String, SysConfig> configMap) {
		BigDecimal todayAddRewardNum = totalHashRate.multiply(dailyOutRate);
		//获取排行分红的系统设置
		BigDecimal currentMonthPoolNum = todayAddRewardNum.multiply(MathUtil.div(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_RATE).getConfValue()), baseNum, 8));
		BigDecimal lastMonthSedimentNum = todayAddRewardNum.multiply(MathUtil.div(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_NEXT_MONTH_SEDIMENT_RATE).getConfValue()), baseNum, 8));
		//首次添加矿池排行奖金池记录
		//获取上个月的矿池奖池记录
		String monthPattern = "yyyy-MM";
		Date currentMonth = new Date();
		Date lastMonth = DateUtils.addMonths(currentMonth, -1);
		String lastMonthStr = DateFormatUtils.format(lastMonth, monthPattern);//上个月
		RankMiningPoolRecord lastMonthRankMiningPoolRecord = rankMiningPoolRecordService.getSomeMonthRecord(lastMonthStr);
		if (!ObjectUtils.isEmpty(lastMonthRankMiningPoolRecord)) {
			currentMonthPoolNum = currentMonthPoolNum.add(lastMonthRankMiningPoolRecord.getLastMonthSedimentNum());
		}
		RankMiningPoolRecord rankMiningPoolRecord = new RankMiningPoolRecord();
		rankMiningPoolRecord.setCurrentMonthPoolNum(currentMonthPoolNum);
		rankMiningPoolRecord.setLastMonthSedimentNum(lastMonthSedimentNum);
		rankMiningPoolRecord.setMiningRate(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_RATE).getConfValue()));
		rankMiningPoolRecord.setSedimentRate(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_NEXT_MONTH_SEDIMENT_RATE).getConfValue()));
		rankMiningPoolRecord.setCreateTime(new Date());
		rankMiningPoolRecordService.save(rankMiningPoolRecord);
		return rankMiningPoolRecord;
	}

	/**
	 * @Description: 更新矿池月奖励记录
	 * @Author: ty
	 * @Date: 2021/5/8 14:56
	 * @param: [rankMiningPoolRecord, totalHashRate, dailyOutRate, configMap]
	 * @return: com.service.dao.model.RankMiningPoolRecord
	 **/
	public RankMiningPoolRecord updateRankMiningPoolRecord(RankMiningPoolRecord rankMiningPoolRecord, BigDecimal totalHashRate, BigDecimal dailyOutRate, Map<String, SysConfig> configMap) {
		BigDecimal todayAddRewardNum = totalHashRate.multiply(dailyOutRate);
		//获取排行分红的系统设置
		BigDecimal currentMonthPoolNum = todayAddRewardNum.multiply(MathUtil.div(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_RATE).getConfValue()), baseNum, 8));
		BigDecimal lastMonthSedimentNum = todayAddRewardNum.multiply(MathUtil.div(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_NEXT_MONTH_SEDIMENT_RATE).getConfValue()), baseNum, 8));
		//更新矿池排行奖金池记录
		rankMiningPoolRecord.setCurrentMonthPoolNum(rankMiningPoolRecord.getCurrentMonthPoolNum().add(currentMonthPoolNum));
		rankMiningPoolRecord.setLastMonthSedimentNum(rankMiningPoolRecord.getLastMonthSedimentNum().add(lastMonthSedimentNum));
		rankMiningPoolRecord.setMiningRate(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_RATE).getConfValue()));
		rankMiningPoolRecord.setSedimentRate(MathUtil.parseBigDecimal(configMap.get(ConfigConstants.RANK_MINING_NEXT_MONTH_SEDIMENT_RATE).getConfValue()));
		rankMiningPoolRecord.setUpdateTime(new Date());
		rankMiningPoolRecordService.updateById(rankMiningPoolRecord);
		return rankMiningPoolRecord;
	}
}
